#include "ArchivoBinario.h"


    /**
    * Abre el archivo ubicado en el path pasado (debe incluir nombre completo) en modo lectura/escritura.
    * Deja el cursor al comienzo del mismo.
    * En caso de no existir el archivo, lo crea.
    * Si no puede realizar la operaci�n, arroja una excepci�n
    */
    ArchivoBinario::ArchivoBinario(const std::string& path):filePathName(path){}

    /**
    * Cierra el archivo (no lo destruye f�sicamente
    */
    ArchivoBinario::~ArchivoBinario(){
       this->cerrar();
    }

    /**
    * Lee del archivo la cantidad de Bytes especificada
    * a partir de la posici�n indicada
    */
    bool ArchivoBinario::leerBytes(int pos, int size, char* const buffer){
    	archivo.seekg(pos);
        archivo.read(buffer,size);
        if (archivo.fail() ) {
        	archivo.clear();
        	return false;
         }
         return true;
    }

    bool ArchivoBinario::leerBloque(int nroBloque, int size, char* const buffer){
    	return this->leerBytes(nroBloque*size,size,buffer);
    }

    bool ArchivoBinario::leerBloque(int size, char* const buffer){
    	return this->leerBytes(archivo.tellg(),size,buffer);
    }


    /**
    * Escribe una cantidad de Bytes en la posici�n indicada
    *  Si no puede escribir, arroja una excepci�n
    */
    void ArchivoBinario::grabarBytes(int pos, unsigned int size, char* const buffer){
        archivo.seekp(pos);
        archivo.write(buffer,size);
    }

    void ArchivoBinario::grabarBloque(int nroBloque, unsigned int size, char* const buffer){
    	this->grabarBytes(nroBloque*size,size,buffer);
    }

    unsigned int ArchivoBinario::agregarBloque(unsigned int size, char* const buffer){
    	unsigned int pos;
    	archivo.seekp(0,std::ios_base::end);
    	pos = archivo.tellp();
    	this->grabarBytes(pos,size,buffer);
    	return pos;
    }

    /**
    * Posiciona el cursor al comienzo del archivo
    */
    void ArchivoBinario::irAlPrincipio(){
        this->archivo.seekg(0);
        this->archivo.seekp(0);
    }

    void ArchivoBinario::cerrar(){
        if (archivo.is_open())
        	archivo.close();
    }

    void ArchivoBinario::abrir(){
    	bool esNuevo;
    	this->abrir(esNuevo);
    }

    void ArchivoBinario::abrir(bool & esNuevo){
    	esNuevo = false;
        //intenta abrir el archivo en modo lectura - escritura
        archivo.open(this->filePathName.c_str(), std::fstream::in | std::fstream::out | std::fstream::binary);

        if (!archivo.is_open()) {
        //si no hubo �xito en la apertura...
        //limpia los flags de control de estado del archivo
        archivo.clear();

        //crea el archivo
        archivo.open(this->filePathName.c_str(), std::fstream::out);
        archivo.close();

        //reabre el archivo para lectura - escritura
        archivo.open(this->filePathName.c_str(), std::fstream::in | std::fstream::out);

        if (!archivo.is_open())
          // si no se pudo crear el archivo arroja una excepci�n/
          throw std::ios_base::failure("El archivo no pudo ser abierto");

        esNuevo = true;
        }

    }

    unsigned int ArchivoBinario::getPosLectura(){
    	unsigned int pos = archivo.tellg();
    	return pos;
    }


